/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package crm.salesOrderProcessing.managedbean;

import commonInfrastructure.accountManagement.entity.SalesmanEntity;
import commonInfrastructure.accountManagement.session.SalesmanSessionBean;
import crm.salesOrderProcessing.entity.DeliveryOrderEntity;
import crm.salesOrderProcessing.entity.SalesOrderEntity;
import crm.salesOrderProcessing.session.SalesOrderSessionBean;
import crm.salesOrderProcessing.util.exception.SalesOrderStatusMismatchException;
import crm.salesOrderProcessing.util.exception.SalesmanAmountLimitExceededException;
import crm.salesOrderProcessing.util.exception.SalesmanNotExistException;
import java.io.IOException;
import java.text.ParseException;
import java.util.Calendar;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.servlet.http.HttpServletRequest;
import mrp.productionPlanning.session.processSalesOrderSessionBean;
import org.primefaces.event.ToggleEvent;
import scm.inventoryControl.session.stateless.InventoryControlSessionBean;

/**
 *
 * @author xhx
 */
@ManagedBean
@ViewScoped
public class ManageSalesOrderManagedBean {

    private SalesOrderEntity salesOrder;
    private String employeeName;
    private String paymentMode;
    private String statusMessage;
    private DeliveryOrderEntity selectedDeliveryOrder;
    private boolean needconfirm;
    private boolean skip = false;
    private boolean largeOrder = false;
    private boolean confirmed;
    private boolean shceduled;
    private boolean needUpdateShipping;
    private boolean needFinalclean;
//    private boolean timerNeed;
//    private int timer = 600;
//    private int hour;
//    private int min;
    @EJB
    SalesmanSessionBean salesmanSessionBean;
    @EJB
    SalesOrderSessionBean salesOrderSessionBean;
    @EJB
    InventoryControlSessionBean inventoryControlSessionBean;
    @EJB
    processSalesOrderSessionBean pssb;

    /** Creates a new instance of ManageSalesOrderManagedBean */
    public ManageSalesOrderManagedBean() {
    }

    public void initView(PhaseEvent event) {
        if (getSalesOrder() == null) {
            setSalesOrder((SalesOrderEntity) FacesContext.getCurrentInstance().getExternalContext().getFlash().get("salesOrder"));
        }
//        hour = timer/60;
//        min = timer%60;
        employeeName = salesOrder.getProcessedBy().getName();
        if (salesOrder.isCashInAdvance()) {
            paymentMode = "Cash In Advance";
        }
        if(!salesOrder.isCashInAdvance()){
             paymentMode = "Credit Sale";
        }
        if (salesOrder.getStatusId() == 50) {
            statusMessage = "Draft";
            shceduled = true;
        }
        if (salesOrder.getStatusId() == 100) {
            statusMessage = "Large Order Wait For Approve";
            largeOrder = true;
            shceduled = true;

        }
        if (salesOrder.getStatusId() == 200) {
            statusMessage = "Sales Order Approved";
            largeOrder = false;
            shceduled = true;
        }
        if (salesOrder.getStatusId() == 300) {
            statusMessage = "Credit Check Passed";
            shceduled = true;
        }
        if (salesOrder.getStatusId() == 400) {
            statusMessage = "ATP check Passed";
            needconfirm = true;
            shceduled = true;
//            timerNeed = true;
        }
        if (salesOrder.getStatusId() == 500) {
            statusMessage = "Confirmed";
            needconfirm = false;
            confirmed = true;
            shceduled = false;
//            timerNeed = false;
        }
        if (salesOrder.getStatusId() == 550) {
            statusMessage = "Production Plan Scheduled";
            confirmed = true;
            shceduled = true;
            needUpdateShipping = true;
        }
        if (salesOrder.getStatusId() == 600) {
            statusMessage = "Awaiting shippment";
            confirmed = true;
            shceduled = true;
            needUpdateShipping = true;
//            timerNeed = false;
        }
        if (salesOrder.getStatusId() == 700) {
            statusMessage = "Partially Shipped";
            confirmed = true;
            shceduled = true;
            needUpdateShipping = true;
        }
        if (salesOrder.getStatusId() == 800) {
            statusMessage = "Fully Shipped";
            confirmed = true;
            shceduled = true;
            needUpdateShipping = false;
            needFinalclean = true;
        }
        if(salesOrder.getStatusId() ==900){
            statusMessage ="Partially Paid";
            shceduled = true;
            needUpdateShipping = false;
            needFinalclean = true;
        }
        if (salesOrder.getStatusId() == 999) {
            statusMessage = "Transaction completed";
            confirmed = true;
            shceduled = true;
            needUpdateShipping = false;
            needFinalclean = false;
        }
    }

    public void handleToggle(ToggleEvent event) {
        FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Fieldset Toggled", "Visibility:" + event.getVisibility());

        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public void amendOrder() throws IOException {
        if (salesOrder.getStatusId() >= 500) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "The Sales Order is Verified Amendation is not allowed", ""));
            return;
        } else {
            FacesContext.getCurrentInstance().getExternalContext().getFlash().put("salesOrder", salesOrder);
            FacesContext.getCurrentInstance().getExternalContext().redirect("amendSalesOrder.xhtml");
        }
    }

    public void updateShippingStatus() throws ParseException {
        int count = 0;
        List<DeliveryOrderEntity> listOfD = salesOrder.getChildDeliveryOrders();
        for (DeliveryOrderEntity d : listOfD) {
            if (d.isIsShipped()) {
                count++;
            }
        }
//          System.out.print("insideTest...." + count);
        if (count == listOfD.size()) {
            salesOrder.setStatusId(800);
            salesOrderSessionBean.saveChanges(salesOrder);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "The Sales Order is full shipped", ""));
            return;
        }
        if (count == 0) {
            salesOrder.setStatusId(600);
            salesOrderSessionBean.saveChanges(salesOrder);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "The Sales Order is waiting for shipment", ""));
            return;
        }
        if (count > 0 && count < listOfD.size()) {
            salesOrder.setStatusId(700);
            salesOrderSessionBean.saveChanges(salesOrder);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "The Sales Order is partially shipped", ""));
            return;
        }
//        if(salesOrder.isCashInAdvance()){
//            boolean flag = false;
//            List<DeliveryOrderEntity> listOfD = salesOrder.getChildDeliveryOrders();
//            for(DeliveryOrderEntity d: listOfD){
//                if(!d.isPaymentStatus() || d.iscIApayment())
//                    flag = false;           
//            }
//            if(flag){
//                salesOrder.setStatusId(700);
//                salesOrderSessionBean.saveChanges(salesOrder);
//                 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "The Sales Order is Ready For Shipping", ""));
//                 return;
//            }
//            else{
//                salesOrder.setStatusId(600);
//                salesOrderSessionBean.saveChanges(salesOrder);
//                 FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "The CIA payment is not Cleand yet, operation denied", ""));
//                 return;
//            }
//        }
//         salesOrder.setStatusId(700);
//         salesOrderSessionBean.saveChanges(salesOrder);
//         FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "The Sales Order is Ready For Shipping", ""));
    }

    public void confirmSalesOrder() throws ParseException {
        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        Long salesManId = (Long) request.getSession().getAttribute("userId");
        SalesmanEntity salesman = salesmanSessionBean.getSalesmanById(salesManId);
        if (salesOrder.getStatusId() >= 400) {

            try {
                salesOrderSessionBean.confirmSalesOrder(salesman, salesOrder);

            } catch (SalesmanAmountLimitExceededException e) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "No enough authority to approve", ""));
                return;

            } catch (SalesmanNotExistException e) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "No Salesman exist", ""));
                return;
            } catch (SalesOrderStatusMismatchException e) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Sales Order Cannot be Confirmed", ""));
                return;
            }

            salesOrder.setStatusId(500);
            salesOrder.setConfirmedBy(salesman);
            salesOrder.setDateConfirmed(Calendar.getInstance().getTime());
            try {
                inventoryControlSessionBean.reserveProduct(salesOrder);
            } catch (EJBException ex) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", ""));
                return;
            }
            salesOrderSessionBean.saveChanges(salesOrder);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Sales Order is Confirmed, and Inventory is reserved", ""));
        } else {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Sales Order is not verifed yet, confirmation is denied.", ""));
        }

    }
//    public void timeCounter(ActionEvent event){
//        if(salesOrder.getStatusId()!=400)
//            return;
//        if(timer == 0)
//            return;
//        timer = timer-1;            
//    }

    public void scheduleOrder() throws ParseException {
        try {
            List<DeliveryOrderEntity> listOfDeliveryOrders = salesOrder.getChildDeliveryOrders();
            for (DeliveryOrderEntity d : listOfDeliveryOrders) {
                pssb.scheduleOrder(d);
            }
        } catch (EJBException ex) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error Occured", ""));
            return;
        }
        salesOrder.setStatusId(550);
        salesOrderSessionBean.saveChanges(salesOrder);
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Production Schedule Created", ""));
    }

    public void finalClean() throws ParseException {
        int countPayment = 0;
        try {
            List<DeliveryOrderEntity> listOfDeliveryOrders = salesOrder.getChildDeliveryOrders();
            for (DeliveryOrderEntity d : listOfDeliveryOrders) {
                if (d.isPaymentStatus()) {
                    countPayment++;
                }
            }
            if (countPayment == 0) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "None of the Delivery Order's payment is Cleaned", ""));
                return;
            }
            if (countPayment > 0 && countPayment < listOfDeliveryOrders.size()) {
                salesOrder.setStatusId(900);
                salesOrderSessionBean.saveChanges(salesOrder);
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "The Sales Order is Partially Paid, some of the Delivery Order is not paid", ""));
                return;
            }
            if (countPayment == listOfDeliveryOrders.size()) {
                salesOrder.setStatusId(999);
                salesOrderSessionBean.saveChanges(salesOrder);
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "The Payment is Cleaned, the transaction for this Sales Order ends!", ""));
                return;
            }
        } catch (EJBException ex) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error Occured", ""));
            return;
        }
    }

    public void approveSalesOrder() throws IOException, ParseException {
        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        Long salesManId = (Long) request.getSession().getAttribute("userId");
        SalesmanEntity salesman = salesmanSessionBean.getSalesmanById(salesManId);

        try {
            salesOrderSessionBean.confirmPendingOrder(salesman, salesOrder, isSkip());

        } catch (SalesmanAmountLimitExceededException e) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "No enough authority to approve", ""));
            return;
        } catch (SalesmanNotExistException e) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Salesman not exist", ""));
            return;
        } catch (SalesOrderStatusMismatchException e) {
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Sales order cannot be approved, unkown error", ""));
            return;
        }
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Large Order Is approved", ""));
    }

    public void viewAll() throws IOException {
        FacesContext.getCurrentInstance().getExternalContext().redirect("viewAllSalesOrder.xhtml");
    }

    public SalesOrderEntity getSalesOrder() {
        return salesOrder;
    }

    public void setSalesOrder(SalesOrderEntity salesOrder) {
        this.salesOrder = salesOrder;
    }

    public String getEmployeeName() {
        return employeeName;
    }

    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }

    public String getPaymentMode() {
        return paymentMode;
    }

    public void setPaymentMode(String paymentMode) {
        this.paymentMode = paymentMode;
    }

    public String getStatusMessage() {
        return statusMessage;
    }

    public void setStatusMessage(String statusMessage) {
        this.statusMessage = statusMessage;
    }

    public DeliveryOrderEntity getSelectedDeliveryOrder() {
        return selectedDeliveryOrder;
    }

    public void setSelectedDeliveryOrder(DeliveryOrderEntity selectedDeliveryOrder) {
        this.selectedDeliveryOrder = selectedDeliveryOrder;
    }

    public boolean isNeedconfirm() {
        return needconfirm;
    }

    public void setNeedconfirm(boolean confirmed) {
        this.needconfirm = confirmed;
    }

    public boolean isSkip() {
        return skip;
    }

    public void setSkip(boolean skip) {
        this.skip = skip;
    }

    public boolean isLargeOrder() {
        return largeOrder;
    }

    public void setLargeOrder(boolean largeOrder) {
        this.largeOrder = largeOrder;
    }

    public boolean isConfirmed() {
        return confirmed;
    }

    public void setConfirmed(boolean confirmed) {
        this.confirmed = confirmed;
    }
//
//    public int getTimer() {
//        return timer;
//    }
//
//    public void setTimer(int timer) {
//        this.timer = timer;
//    }
//
//    public boolean isTimerNeed() {
//        return timerNeed;
//    }
//
//    public void setTimerNeed(boolean timerNeed) {
//        this.timerNeed = timerNeed;
//    }
//
//    public int getHour() {
//        return hour;
//    }
//
//    public void setHour(int hour) {
//        this.hour = hour;
//    }
//
//    public double getMin() {
//        return min;
//    }
//
//    public void setMin(int min) {
//        this.min = min;
//    }

    public boolean isShceduled() {
        return shceduled;
    }

    public void setShceduled(boolean shceduled) {
        this.shceduled = shceduled;
    }

    public boolean isNeedUpdateShipping() {
        return needUpdateShipping;
    }

    public void setNeedUpdateShipping(boolean needUpdateShipping) {
        this.needUpdateShipping = needUpdateShipping;
    }

    public boolean isNeedFinalclean() {
        return needFinalclean;
    }

    public void setNeedFinalclean(boolean needFinalclean) {
        this.needFinalclean = needFinalclean;
    }
}
